/**********************************************
 * 	TestIntegration.java					  *
 *  Course: CS3343							  *
 *  Version: 2.5    Release 3				  *
 *  Last Modified : 22 MAR 2013			      *
 **********************************************/
package testChecker;

import org.junit.Before;

import junit.framework.TestCase;
import org.junit.Test;

import testFile.TestFileIO;
import checker.*;
import java.util.*;

public class TestIntegration extends TestCase {

	@Before
	public void setUp() throws Exception {

	}

	// run all the test cases in the TestDictionary class to test Dictionary
	// class
	@Test
	public void testDictionary() {
		TestDictionary testDictionary;
		testDictionary = new TestDictionary() {
			protected void runTest() {
				testSpellingA();
				testSpellingB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();


			}
		};
		testDictionary.run();
	}

	// run all the test cases in the TestNoun class to test the Noun class
	@Test
	public void testNoun() {
		TestNoun testNoun;
		testNoun = new TestNoun() {
			protected void runTest() {
				testNounA();
				testNounB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();
				testUserDefinedConstructor();
			}
		};

		testNoun.run();
	}

	// run all the test cases in the TestVerb class to test the Verb class
	@Test
	public void testVerb() {
		TestVerb testVerb;
		testVerb = new TestVerb() {
			protected void runTest() {
				testVerbA();
				testVerbB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();
				testUserDefinedConstructor();
			}
		};

		testVerb.run();
	}

	// run all the test cases in the TestPreposition class to test the Preposition class
	@Test
	public void testPreposition() {
		TestPreposition testPreposition;
		testPreposition = new TestPreposition() {
			protected void runTest() {
				testPrepositionA();
				testPrepositionB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();
				testUserDefinedConstructor();
			}
		};
		testPreposition.run();
	}

	// run all the test cases in the TestPreposition class to test the Adjective class
	@Test
	public void testAdjective() {
		TestAdjective testAdjective;
		testAdjective = new TestAdjective() {
			protected void runTest() {
				testAdjectiveA();
				testAdjectiveB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();
				testUserDefinedConstructor();
			}
		};
		testAdjective.run();

	}

	// run all the test cases in the TestAdverb class to test the Adverb class
	@Test
	public void testAdverb() {
		TestAdverb testAdverb;
		testAdverb = new TestAdverb() {
			protected void runTest() {
				testAdverbA();
				testAdverbB();
				testIntegrationWithFileIO1();
				testIntegrationWithFileIO2();
				testIntegrationWithFileIO3();
				testIntegrationWithFileIO4();
				testIntegrationWithFileIO5();
				testIntegrationWithFileIO6();
				testUserDefinedConstructor();
			}
		};
		testAdverb.run();

	}

	// run all the test cases in the TestSentenceChecker class to test the SentenceChecker class
	@Test
	public void testSentenceChecker() {
		TestSentenceChecker testSentenceChecker;
		testSentenceChecker = new TestSentenceChecker() {
			protected void runTest() {
				testCapitalA();
				testCapitalB();
				testPunctuationA();
				testPunctuationB();
				testPunctuationC();
				testSentenceA();
				testSentenceB();
				testIntegrationA();
				testIntegrationB();
			}

		};
		testSentenceChecker.run();
	}

	// run all the test cases in the TestReadFile class to test the SentenceChecker class
	@Test
	public void testFileIO() {
		TestFileIO fileIO;
		fileIO = new TestFileIO() {
			protected void runTest() {
				testReadFile();
				testWriteFile();
			}

		};
		fileIO.run();
	}

	//this is the test of the find() function in the Word class that identifies
	// a specific type of words
	@Test
	public void testFindNoun() {
		Word noun = new Noun();
		noun.setSign("[n]");
		String[] result = noun.find("article2.txt", noun);
		boolean pass = true;

		//The found words are kept in the format of "index/word" such as "2/Hello".
		//Therefore, the split() function is used to separate them for access different values
		System.out.println("\nTest finding nouns...");
		String[] indexAndWord = result[0].split("/");
		System.out.println("\nExpected output:\n2 measurements");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
		if(!indexAndWord[0].equalsIgnoreCase("2") || !indexAndWord[1].equalsIgnoreCase("measurements"))
			pass = false;
		
		indexAndWord = result[1].split("/");
		System.out.println("\nExpected output:\n7 average");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
		if(!indexAndWord[0].equalsIgnoreCase("7") || !indexAndWord[1].equalsIgnoreCase("average"))
			pass = false;

		indexAndWord = result[2].split("/");
		System.out.println("\nExpected output:\n8 temperature");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
		if(!indexAndWord[0].equalsIgnoreCase("8") || !indexAndWord[1].equalsIgnoreCase("temperature"))
			pass = false;

		indexAndWord = result[3].split("/");
		System.out.println("\nExpected output:\n14 degree");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1] + "\n");
		if(!indexAndWord[0].equalsIgnoreCase("14") || !indexAndWord[1].equalsIgnoreCase("degree"))
			pass = false;

		indexAndWord = result[4].split("/");
		System.out.println("\nExpected output:\n15 centigrade");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1] + "\n");
		if(!indexAndWord[0].equalsIgnoreCase("15") || !indexAndWord[1].equalsIgnoreCase("centigrade"))
			pass = false;

		indexAndWord = result[5].split("/");
		System.out.println("\nExpected output:\n16 over");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1] + "\n");
		if(!indexAndWord[0].equalsIgnoreCase("16") || !indexAndWord[1].equalsIgnoreCase("over"))
			pass = false;

		indexAndWord = result[6].split("/");
		System.out.println("\nExpected output:\n18 past");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1] + "\n");
		if(!indexAndWord[0].equalsIgnoreCase("18") || !indexAndWord[1].equalsIgnoreCase("past"))
			pass = false;


		indexAndWord = result[7].split("/");
		System.out.println("\nExpected output:\n20 years");
		System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1] + "\n");
		if(!indexAndWord[0].equalsIgnoreCase("20") || !indexAndWord[1].equalsIgnoreCase("years"))
			pass = false;
		assertEquals(true,pass);
	}



	/* This is an integration test that tests the function that reads contents 
	 * from a text file, processes the contents and finally output the results. 
	 * This function finds all types of words and output them to a text file.
	 */
	@Test
	public void testFindAll() {
		try{

			/* The Word is an abstract class that cannot be instantiated.
			 * However, each subclass of it can use the findAll() function 
			 * to find out all types of words
			 */
			Word word = new Noun();
			boolean pass = true;
			String expectedResult = "The[adv] observational[adj] measurements[n] conclude[v] that[adv] the[adv] global[adj] average[adj] temperature[n] has[v] increased[adj] \r\n" +
			"by[pre] about[adj] 0.5 degree[adj] centigrade[adj] over[adj] the[adv] past[adj] 100 years[n].";
			//ArrayList:
			// index 0: array of adjectives
			// index 1: array of nouns
			// index 2: array of verbs
			// index 3: array of adverbs
			// index 4: array of prepositions
			ArrayList<String[]> foundWords = word.findAll("article2.txt", "article2Output.txt");

			String[] indexAndWord = foundWords.get(0)[0].split("/");
			System.out.println("\nExpected output:\n1 observational");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("1") || !indexAndWord[1].equalsIgnoreCase("observational"))
				pass = false;

			indexAndWord = foundWords.get(0)[2].split("/");
			System.out.println("\nExpected output:\n7 average");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("7") || !indexAndWord[1].equalsIgnoreCase("average"))
				pass = false;

			indexAndWord = foundWords.get(1)[0].split("/");
			System.out.println("\nExpected output:\n2 measurements");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("2") || !indexAndWord[1].equalsIgnoreCase("measurements"))
				pass = false;

			indexAndWord = foundWords.get(1)[2].split("/");
			System.out.println("\nExpected output:\n20 years");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("20") || !indexAndWord[1].equalsIgnoreCase("years"))
				pass = false;

			indexAndWord = foundWords.get(2)[0].split("/");
			System.out.println("\nExpected output:\n3 conclude");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("3") || !indexAndWord[1].equalsIgnoreCase("conclude"))
				pass = false;

			indexAndWord = foundWords.get(2)[1].split("/");
			System.out.println("\nExpected output:\n9 has");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("9") || !indexAndWord[1].equalsIgnoreCase("has"))
				pass = false;

			indexAndWord = foundWords.get(3)[0].split("/");
			System.out.println("\nExpected output:\n0 the");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("0") || !indexAndWord[1].equalsIgnoreCase("the"))
				pass = false;

			indexAndWord = foundWords.get(3)[1].split("/");
			System.out.println("\nExpected output:\n4 that");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("4") || !indexAndWord[1].equalsIgnoreCase("that"))
				pass = false;

			indexAndWord = foundWords.get(4)[0].split("/");
			System.out.println("\nExpected output:\n11 by");
			System.out.println("Actual output:\n"+indexAndWord[0] + " " + indexAndWord[1]);
			if(!indexAndWord[0].equalsIgnoreCase("11") || !indexAndWord[1].equalsIgnoreCase("by"))
				pass = false;


			String result = word.getModifiedArticle();

			System.out.println("\nExpected output:\n" + expectedResult);
			System.out.println("Actual output:\n"+result.trim());


			if(!expectedResult.equalsIgnoreCase(result.trim()))
				pass = false;

			assertEquals(true,pass);


		}catch(Exception ex){
			ex.printStackTrace();
		}
	}

}
